﻿using ActionFilterPlugin;
using CommonLibary;
using ConfigurationCommon;
using DataBaseCommon;
using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.HttpLogging;
using Microsoft.AspNetCore.Mvc.Filters;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.PlatformAbstractions;
using Microsoft.Extensions.Primitives;
using Microsoft.IdentityModel.Tokens;
using Microsoft.OpenApi.Models;
using MongoDB.Driver;
using NetCore6WebAPITestOneEntity;
using NetCroe6WebAPITestOneBusiness;
using NetCroe6WebAPITestOneResponse;
using Org.BouncyCastle.Asn1.X509.Qualified;
using RabbitMQPlugin;
using SqlSugar;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace MiddlewarePlugins
{
    public static class InitializationMiddlrwarePlugin
    {
        public static void InitBuilder(this WebApplicationBuilder builder) {

            #region w3clogger配置
            builder.Services.AddW3CLogging(logging =>
            {
                // Log all W3C fields
                logging.LoggingFields = W3CLoggingFields.All;

                logging.FileSizeLimit = 5 * 1024 * 1024;
                logging.RetainedFileCountLimit = 2;
                logging.FileName = "MyLogFile";
                logging.LogDirectory = @"C:\logs";
                logging.FlushInterval = TimeSpan.FromSeconds(2);
            });
            #endregion

            #region 配置swagger
            //builder.Services.AddSwaggerGen();
            //描述信息添加
            builder.Services.AddSwaggerGen(options =>
            {
                options.SwaggerDoc("v1", new OpenApiInfo
                {
                    Version = "v1",
                    Title = "接口",
                    Description = "一个webapi接口站点",
                    //TermsOfService = new Uri("https://example.com/terms"),
                    //Contact = new OpenApiContact
                    //{
                    //    Name = "Example Contact",
                    //    Url = new Uri("https://example.com/contact")
                    //},
                    //License = new OpenApiLicense
                    //{
                    //    Name = "Example License",
                    //    Url = new Uri("https://example.com/license")
                    //}
                });
                //增加swagger auth header
                options.AddSecurityDefinition("bearerAuth", new OpenApiSecurityScheme
                {
                    Type = SecuritySchemeType.Http,
                    Scheme = "bearer",
                    BearerFormat = "JWT",
                    Description = "JWT Authorization header using the Bearer scheme."
                });
                options.AddSecurityRequirement(new OpenApiSecurityRequirement
                    {
                        {
                            new OpenApiSecurityScheme
                            {
                                Reference = new OpenApiReference { Type = ReferenceType.SecurityScheme, Id = "bearerAuth" }
                            },
                            new string[] {}
                        }
                    });

                //释放xml节点注释，Assmbily要添加节点<PropertyGroup><GenerateDocumentationFile>true</GenerateDocumentationFile></PropertyGroup>
                foreach (var item in XmlCommentsFilePath)
                {
                    options.IncludeXmlComments(item);
                }
            });
            #endregion

            #region 配置文件配置
            //options配置json数据
            var appsetting1ConfigruationRoot = new ConfigurationBuilder() { }.AddJsonFile("appsettings1.json").Build();
            builder.Services.Configure<AppSettingsModel>(appsetting1ConfigruationRoot);
            //builder.Services.AddOptions<AppSettingsModel>().Configure(option => option.Name = "直接赋值");
            //带option的示例
            var appsetting2ConfigruationRoot = new ConfigurationBuilder() { }.AddJsonFile("appsettings2.json").Build();
            builder.Services.Configure<AppSettingsModel>("mongodb", appsetting2ConfigruationRoot.GetSection("mongodb"))
               .Configure<AppSettingsModel>("mysql", appsetting2ConfigruationRoot.GetSection("mysql"));

            builder.Services.Configure<RabbitMQServicesModel>(builder.Configuration.GetSection("MQ"));
            #endregion

            #region 通过DI扩展scrutor来实现注册程序集（也可以使用第三方autofac）
            builder.Services.Scan(scan => scan.FromAssemblyOf<WeatherForecastBusiness>().AddClasses(classes => classes.Where(t =>
            t.Name.EndsWith("Business"))).AsSelf()
            //.AsMatchingInterface()
            .WithScopedLifetime());
            builder.Services.Scan(scan => scan.FromAssemblyOf<WeatherForecastResponse>().AddClasses(classes => classes.Where(t => t.Name.EndsWith("Response")))
            .AsSelf().WithScopedLifetime());
            //服务注册
            builder.Services.Scan(scan => {
                scan.FromAssemblyOf<ConfigurationScopeHelper>().AddClasses(classes => classes.Where(t => t.Name.EndsWith("ScopeHelper"))).AsSelf().WithScopedLifetime();
                scan.FromAssemblyOf<ConfigurationScopeHelper>().AddClasses(classes => classes.Where(t => t.Name.EndsWith("SingletonHelper"))).AsSelf().WithScopedLifetime();
                scan.FromAssemblyOf<ConfigurationScopeHelper>().AddClasses(classes => classes.Where(t => t.Name.EndsWith("TransientHelper"))).AsSelf().WithScopedLifetime();
            });

            builder.Services.AddScoped<ISqlSugarClient>(it => new SqlSugarClient(new List<ConnectionConfig>() {
                new ConnectionConfig() { ConnectionString="",ConfigId=1,DbType=DbType.SqlServer,IsAutoCloseConnection=true},
                }){ });

            builder.Services.Scan(s =>
            {
                s.FromAssemblyOf<WebClientSingletonHelper>().AddClasses(c => c.Where(t => t.Name.EndsWith("SingletonHelper"))).AsSelf().WithSingletonLifetime();
            });

            builder.Services.Scan(s =>
            {
                s.FromAssemblyOf<MongoDbClientScopedHelper>().AddClasses(c => c.Where(t => t.Name.EndsWith("SingletonHelper"))).AsSelf().WithSingletonLifetime();
                s.FromAssemblyOf<MongoDbClientScopedHelper>().AddClasses(c => c.Where(t => t.Name.EndsWith("ScopedHelper"))).AsSelf().WithScopedLifetime();
                s.FromAssemblyOf<MongoDbClientScopedHelper>().AddClasses(c => c.Where(t => t.Name.EndsWith("TransientHelper"))).AsSelf().WithTransientLifetime();
            });

            builder.Services.Scan(s =>
            {
                s.FromAssemblyOf<RabbitMQModule>().AddClasses(c => c.Where(t => t.Name.EndsWith("Helper"))).AsSelf().WithSingletonLifetime();
            });

            builder.Services.Scan(s =>
            {
                s.FromAssemblyOf<ComActionFilter>().AddClasses(c=>c.Where(t=>t.Name.EndsWith("Helper"))).AsSelf().WithScopedLifetime();
            });
            #endregion

            //httpclient服务注册
            builder.Services.AddHttpClient();

            #region 配置使用 XmlSerializer 实现的 XML 格式化程序
            builder.Services.AddControllers().AddXmlSerializerFormatters();
            #endregion

            #region jwtbearer
            string secKey = builder.Configuration.GetSection("JWT:SecKey").Value;
            SymmetricSecurityKey byteSecKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(secKey));
            builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme).AddJwtBearer(x => {
                x.TokenValidationParameters = new TokenValidationParameters()
                {
                    ValidateIssuer = false,
                    ValidateAudience = false,
                    ValidateLifetime = true,
                    ValidateIssuerSigningKey = true,
                    IssuerSigningKey = byteSecKey
                };
            });
            #endregion

            //memcached
            //builder.Services.AddEnyimMemcached();
            //services.AddEnyimMemcached(Configuration);
            //services.AddEnyimMemcached(Configuration, "enyimMemcached");
            builder.Services.AddEnyimMemcached(builder.Configuration.GetSection("enyimMemcached"));
            //builder.Services.AddEnyimMemcached(options => options.AddServer("127.0.0.1", 11211));

            builder.Services.AddScoped<IMongoClient, MongoClient>();

            //消费者host订阅
            builder.Services.AddHostedService<RabbitMQConsumerService>();
        }

        public static void InitApp(this WebApplication app) {


            #region w3clogger
            app.UseW3CLogging();
            #endregion

            #region swagger
            // Configure the HTTP request pipeline.
            if (app.Environment.IsDevelopment())
            {
                //app.UseSwagger();
                //app.UseSwaggerUI();
                //根节点提供swagger
                //app.UseSwaggerUI(options =>
                //{
                //    options.SwaggerEndpoint("/swagger/v1/swagger.json", "v1");
                //    options.RoutePrefix = string.Empty;
                //});
            }
            app.UseSwagger();
            app.UseSwaggerUI();
            #endregion

            //jwtbearer
            app.UseAuthentication();//auth验证
            app.UseAuthorization();

            //memcached
            app.UseEnyimMemcached();
        }

        static List<string> XmlCommentsFilePath
        {
            get
            {
                var basePath = PlatformServices.Default.Application.ApplicationBasePath;
                DirectoryInfo d = new DirectoryInfo(basePath);
                FileInfo[] files = d.GetFiles("*.xml");
                var xmls = files.Select(a => Path.Combine(basePath, a.FullName)).ToList();
                return xmls;
            }
        }
    }
}
